"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Tile_1 = __importDefault(require("./TileImpl/Tile"));
const isValidGeographicBbox_1 = __importDefault(require("./isValidGeographicBbox"));
const turf_1 = __importDefault(require("../../../ext/turf"));
class TileSet {
    tileObj;
    constructor() {
        this.tileObj = {};
    }
    add(x, y, zoom) {
        let zObj = this.tileObj[zoom];
        if (!zObj) {
            zObj = {};
            this.tileObj[zoom] = zObj;
        }
        let xObj = this.tileObj[zoom][x];
        if (!xObj) {
            xObj = {};
            this.tileObj[zoom][x] = xObj;
        }
        xObj[y] = true;
    }
    getMaxZoom() {
        let maxZoom = 0;
        for (const zoom in this.tileObj) {
            if (Number(zoom) > maxZoom)
                maxZoom = Number(zoom);
        }
        return maxZoom;
    }
    getMinZoom() {
        let minZoom = 0;
        for (const zoom in this.tileObj) {
            if (Number(zoom) < minZoom)
                minZoom = Number(zoom);
        }
        return minZoom;
    }
    getTilingScheme() {
        const maxZoom = this.getMaxZoom();
        const { default: TileUtil3857 } = require('./TileUtil3857');
        const { default: TileUtil4326 } = require('./TileUtil4326');
        const tileTool3857 = new TileUtil3857();
        const tileTool4326 = new TileUtil4326();
        if (maxZoom === 0) {
            return null;
        }
        else {
            const randomX = Object.keys(this.tileObj[maxZoom])[0];
            const randomY = Object.keys(this.tileObj[maxZoom][randomX])[0];
            const tile = { x: Number(randomX), y: Number(randomY), zoom: Number(maxZoom) };
            const bbox3857 = tileTool3857.tileXYZToRectanglePolygon(tile.x, tile.y, tile.zoom).bbox;
            const bbox4326 = tileTool4326.tileXYZToRectanglePolygon(tile.x, tile.y, tile.zoom).bbox;
            if ((0, isValidGeographicBbox_1.default)(bbox3857)) {
                return 'layer-xyz-3857';
            }
            else if ((0, isValidGeographicBbox_1.default)(bbox4326)) {
                return 'layer-xyz-4326';
            }
            else {
                return null;
            }
        }
    }
    getRectangle() {
        const maxZoom = this.getMaxZoom();
        const tilingScheme = this.getTilingScheme();
        const tileList = this.getAll().filter(tile => tile.zoom === maxZoom);
        const { default: TileUtil3857 } = require('./TileUtil3857');
        const { default: TileUtil4326 } = require('./TileUtil4326');
        const tileTool = tilingScheme === 'layer-xyz-3857' ? new TileUtil3857() : new TileUtil4326();
        if (tilingScheme === 'layer-xyz-3857') {
            const geoJson = {
                type: 'FeatureCollection',
                features: []
            };
            for (let i = 0; i < tileList.length; i++) {
                const json = tileTool.tileXYZToRectanglePolygon(tileList[i].x, tileList[i].y, tileList[i].zoom);
                geoJson.features.push(json);
            }
            const bbox = turf_1.default.bbox(geoJson);
            return {
                east: bbox[2],
                north: bbox[3],
                south: bbox[1],
                west: bbox[0]
            };
        }
        else if (tilingScheme === 'layer-xyz-4326') {
            const geoJson = {
                type: 'FeatureCollection',
                features: []
            };
            for (let i = 0; i < tileList.length; i++) {
                const json = tileTool.tileXYZToRectanglePolygon(tileList[i].x, tileList[i].y, tileList[i].zoom);
                geoJson.features.push(json);
            }
            const bbox = turf_1.default.bbox(geoJson);
            return {
                east: bbox[2],
                north: bbox[3],
                south: bbox[1],
                west: bbox[0]
            };
        }
        return {
            east: 180,
            north: 90,
            south: -90,
            west: -180
        };
    }
    getLayerProperties() {
        const minZoom = this.getMinZoom();
        const maxZoom = this.getMaxZoom();
        const tilingScheme = this.getTilingScheme();
        const rectangle = this.getRectangle();
        return {
            scheme: tilingScheme,
            minimumLevel: minZoom,
            maximumLevel: maxZoom,
            rectangle: rectangle,
        };
    }
    delete(x, y, zoom) {
        if (this.tileObj[zoom] && this.tileObj[zoom][x] && this.tileObj[zoom][x][y])
            this.tileObj[zoom][x][y] = false;
    }
    getAll() {
        const result = [];
        for (const zoom in this.tileObj) {
            for (const x in this.tileObj[zoom]) {
                for (const y in this.tileObj[zoom][x]) {
                    if (this.tileObj[zoom][x][y] === true) {
                        result.push(new Tile_1.default(Number(x), Number(y), Number(zoom)));
                    }
                }
            }
        }
        return result;
    }
    clear() {
        this.tileObj = {};
    }
}
exports.default = TileSet;
